﻿using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.Xna.Framework.Resources;

namespace Microsoft.Xna.Framework
{
    /// <summary>
    /// 	A collection of game services.
    /// </summary>
    public class GameServiceContainer : IServiceProvider
    {
        #region Collection Fields & Properties

        private readonly Dictionary<Type, object> _services = new Dictionary<Type, object>();

        #endregion

        #region Implementation of IServiceProvider

        /// <summary>
        /// 	Gets the object providing a specified service.
        /// </summary>
        /// <param name = "type">The type of service.</param>
        public object GetService(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type", Resx.ServiceTypeCannotBeNull);
            }
            if (_services.ContainsKey(type))
            {
                return _services[type];
            }
            return null;
        }

        #endregion

        #region Add & Remove Service

        /// <summary>
        /// 	Adds a service to the GameServiceContainer.
        /// </summary>
        /// <param name = "type">The type of service to add.</param>
        /// <param name = "provider">The service provider to add.</param>
        public void AddService(Type type, object provider)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type", Resx.ServiceTypeCannotBeNull);
            }
            if (provider == null)
            {
                throw new ArgumentNullException("provider", Resx.ServiceProviderCannotBeNull);
            }
            if (_services.ContainsKey(type))
            {
                throw new ArgumentException(Resx.ServiceAlreadyPresent, "type");
            }
            if (!type.IsAssignableFrom(provider.GetType()))
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, Resx.ServiceMustBeAssignable, provider.GetType().FullName, type.GetType().FullName));
            }
            _services.Add(type, provider);
        }

        /// <summary>
        /// 	Removes the object providing a specified service.
        /// </summary>
        /// <param name = "type">The type of service.</param>
        public void RemoveService(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type", Resx.ServiceTypeCannotBeNull);
            }
            _services.Remove(type);
        }

        #endregion
    }
}